/*
 * File      : fh_aes.h
 *
 * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
 * All rights reserved
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *  Visit http://www.fullhan.com to get contact with Fullhan.
 *
 * Change Logs:
 * Date           Author       Notes
 */


#ifndef FH_AES_H_
#define FH_AES_H_

#include "algorithm_core.h"
#ifndef NULL
#define NULL 0
#endif

#define MAX_EFUSE_MAP_SIZE              8

#define IOCTL_EFUSE_CHECK_PRO           0
#define IOCTL_EFUSE_WRITE_KEY           1
#define IOCTL_EFUSE_READ_KEY            2
#define IOCTL_EFUSE_CHECK_LOCK          3
#define IOCTL_EFUSE_TRANS_KEY           4
#define IOCTL_EFUSE_CHECK_ERROR         5
#define IOCTL_EFUSE_WRITE_ENTRY         6
#define IOCTL_EFUSE_READ_ENTRY          7
#define IOCTL_EFUSE_SET_LOCK_DATA       8
#define IOCTL_EFUSE_SET_MAP_PARA_4_TO_1     10
#define IOCTL_EFUSE_SET_MAP_PARA_1_TO_1     11
#define IOCTL_EFUSE_CLR_MAP_PARA            12

#define IOCTL_EFUSE_WRITE_BIT               30
#define IOCTL_EFUSE_SET_LOCK_WRITE_DATA     31
#define IOCTL_EFUSE_MEM_CMP               32

#define OPEN_4_ENTRY_TO_1_KEY           0x55
#define OPEN_1_ENTRY_TO_1_KEY           0xaa

#define IOCTL_EFUSE_DEBUG           55
#define IOCTL_EFUSE_DUMP_REGISTER       120
#define EFUSE_DEBUG_WRITE_ENTRY         0x55AAAA55

struct fh_aes_reg_v2
{
    u32 encrypt_control;        /* 0 */
    u32 clk_gating_bypass;      /* 4 */
    u32 fifo_status;            /* 8 */
    u32 parity_error;           /* c */
    u32 security_key0;          /* 10 */
    u32 security_key1;          /* 14 */
    u32 security_key2;          /* 18 */
    u32 security_key3;          /* 1c */
    u32 security_key4;          /* 20 */
    u32 security_key5;          /* 24 */
    u32 security_key6;          /* 28 */
    u32 security_key7;          /* 2c */
    u32 initial_vector0;        /* 30 */
    u32 initial_vector1;        /* 34 */
    u32 initial_vector2;        /* 38 */
    u32 initial_vector3;        /* 3c */
    u32 dma_src_add;            /* 40 */
    u32 reserved_44;            /* 44 */
    u32 dma_dst_add;            /* 48 */
    u32 reserved_4c;            /* 4c */
    u32 dma_trans_size;         /* 50 */
    u32 dma_control;            /* 54 */
    u32 fifo_threshold;         /* 58 */
    u32 intr_enable;            /* 5c */
    u32 intr_src;               /* 60 */
    u32 mask_intr_status;       /* 64 */
    u32 intr_clear;             /* 68 */
    u32 debug[5];               /* 6c ~ 7c*/	
    u32 last_initial_vector0;   /* 80 */
    u32 last_initial_vector1;   /* 84 */
    u32 last_initial_vector2;   /* 88 */
    u32 last_initial_vector3;   /* 8c */
    u32 ext_dma_cfg_0;          /* 90 */
    u32 ext_dma_cfg_1;          /* 94 */
    u32 ext_dma_cfg_2;          /* 98 */
    u32 ext_dma_cfg_3;          /* 9c */
    u32 res_aes_key_0;          /* 100 */
    u32 res_aes_key_1;          /* 104 */
    u32 res_aes_key_2;          /* 108 */
    u32 res_aes_key_3;          /* 10c */
    u32 res_aes_key_4;          /* 110 */
    u32 res_aes_key_5;          /* 114 */
    u32 res_aes_key_6;          /* 118 */
    u32 res_aes_key_7;          /* 11c */
};

struct fh_aes_platform_data
{
    u32 id;
    u32 irq;
    u32 base;

    u32 efuse_base;
    u32 aes_support_flag;
};
struct wrap_efuse_obj;
struct fh_aes_driver_v2
{

    void *regs;
    u32 id;
    u32 irq_no;                 /* board info... */
    u32 open_flag;
    /* below are driver use */
    u32 irq_en;
    /* sys lock */
    /* isr */
    u32 control_mode;
    u32 iv_flag;

    /* driver could find the core data... */
    struct rt_crypto_obj *cur_crypto;
    struct rt_crypto_request *cur_request;

    //bind one status to efuse ..
    struct wrap_efuse_obj *p_efuse;
};

/*add efuse_aes_map struct*/
struct efuse_aes_map {
    u32 aes_key_no;
    u32 efuse_entry;
};

struct efuse_aes_map_para {
    u32 open_flag;
    u32 map_size;
    struct efuse_aes_map map[MAX_EFUSE_MAP_SIZE];
};

struct efuse_status
{
    /* bit 1 means could write..0 not write
     * 64block version: bit0 ~ bit63
     * 16block version: bit0 ~ bit15
     */
    u32 protect_bits[2];
    /*
     * 64block version: bit0: block0 ~ block3	[readlock]
     *                  bit1: block4 ~ block7	[readlock]
     *                  ...
     *                  bit14: block56 ~ block59[readlock]
     *
     * 16block version: bit0: block0 ~ block3	[readlock]
     *                  bit1: block4 ~ block7	[readlock]
     *                  bit2: block8 ~ block11	[readlock]
     */
    u32 efuse_apb_lock;
    /*
     * bit0: aes key0 & key1	[readlock]
     * bit1: aes key2 & key3	[readlock]
     * bit2: aes key4 & key5	[readlock]
     * bit3: aes key6 & key7	[readlock]
     */
    u32 aes_ahb_lock;
    u32 error;
    /*
     * bit[i]---map to---block[i]
     * 64block version: bit0 ~ bit56	[writelock]
     * 16block version: bit0 ~ bit11	[writelock]
     */
    u32 efuse_write_lock[2];
};

typedef struct {
    /* write key */
    u32 efuse_entry_no; /* from 0 ~ 31 */
    u8 *key_buff;
    u32 key_size;
    /* trans key */
    u32 trans_key_start_no; /* from 0 ~ 7 */
    u32 trans_key_size;     /* max 8 */
    /* status */
    u32 cmd;
    u32 addr;
    u32 wvalue;
    u32 aeskeyid;
    u32 wvalue_data;

    u32 bit_pos;
    u32 bit_val;
    struct efuse_status status;
/* u32 status;           //process status back to app. */
} EFUSE_INFO_V2;

struct wrap_efuse_obj {
    void *regs;
    /*write key*/
    u32 efuse_entry_no;     /*from 0~31*/
    u8 *key_buff;
    u32 key_size;
    /*trans key*/
    u32 trans_key_start_no; /*from 0~7*/
    u32 trans_key_size;     /*max 8*/
    /*status*/
    struct efuse_status status;

} ;


#define AES_FLAG_SUPPORT_CPU_SET_KEY            CRYPTO_CPU_SET_KEY
#define AES_FLAG_SUPPORT_EFUSE_SET_KEY          CRYPTO_EX_MEM_SET_KEY

long fh_efuse_ioctl(EFUSE_INFO_V2 *efuse_user_info, unsigned int cmd,
        unsigned long arg);

void *get_efuse_handle(void);
void refresh_efuse(struct wrap_efuse_obj *obj);
void efuse_read_entry(struct wrap_efuse_obj *obj, u32 key, u32 start_entry, u8 *buff,
        u32 size);
void efuse_write_key_byte(struct wrap_efuse_obj *obj, u32 entry, u8 data);
#endif

/* FH_AES_H_ */
